package com.bwstudio.demo.provider.service;

import java.math.BigDecimal;

import javax.annotation.Resource;

import lombok.RequiredArgsConstructor;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.bwstudio.demo.provider.dao.AccountInfoDao;
import com.bwstudio.demo.provider.model.AccountChangeEvent;

import lombok.extern.slf4j.Slf4j;

/**
 * @author buwei
 */
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AccountInfoServiceImpl implements AccountInfoService {

	private final AccountInfoDao accountInfoDao;

	private final RocketMQTemplate rocketMQTemplate;

	// 向mq发送转账消息
	@Override
	public void sendUpdateAccountBalance(AccountChangeEvent accountChangeEvent, String tag) {

		// 将accountChangeEvent转成json
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("accountChange", accountChangeEvent);
		String jsonString = jsonObject.toJSONString();
		// 生成message类型
		Message<String> message = MessageBuilder.withPayload(jsonString).build();
		// 发送一条事务消息
		/**
		 * String txProducerGroup 生产组 
		 * String destination topic， 
		 * Message<?> message, 消息内容
		 * Object arg 参数
		 */
		//rocketMQTemplate.sendMessageInTransaction("producer_group_txmsg_bank1", "topic_txmsg:" + tag, message, null);
		rocketMQTemplate.sendMessageInTransaction("topic_txmsg:" + tag, message, null);
	}

	// 更新账户，扣减金额
	@Override
	@Transactional
	public void doUpdateAccountBalance(AccountChangeEvent accountChangeEvent) {
		// 幂等判断
		if (accountInfoDao.isExistTx(accountChangeEvent.getTxNo()) > 0) {
			return;
		}
		// 扣减金额
		accountInfoDao.updateAccountBalance(accountChangeEvent.getAccountNo(), accountChangeEvent.getAmount().multiply(new BigDecimal(-1)));
		// 添加事务日志
		accountInfoDao.addTx(accountChangeEvent.getTxNo());
		if (accountChangeEvent.getAmount().compareTo(new BigDecimal(3)) == 0) {
			throw new RuntimeException("人为制造异常");
		}
	}
}